﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using ArcEngine;
using System.IO;
using System.Drawing;

namespace DungeonEye
{

	/// <summary>
	/// Represent a dungeon which contains severals levels
	/// </summary>
	public class Dungeon
	{
		public Dungeon()
		{
			mazes = new Dictionary<string, Maze>();
		}



		/// <summary>
		/// Initialize the dungeon
		/// </summary>
		/// <returns></returns>
		public bool Init()
		{
			foreach (Maze level in mazes.Values)
				level.Init();

			return true;
		}


		/// <summary>
		/// Draw a level of the dungeon
		/// </summary>
		/// <param name="maze"></param>
		/// <param name="location"></param>
		/// <param name="direction"></param>
		public void Draw(Maze maze, Point location, Compass direction)
		{
			if (maze == null)
				return;

			maze.Draw(location, direction);

		}



		/// <summary>
		/// Update all elements in the dungeon
		/// </summary>
		public void Update()
		{
			foreach (Maze level in Mazes)
			{
				level.Update();
			}
		}



		#region IO

		/// <summary>
		/// 
		/// </summary>
		/// <param name="filename"></param>
		/// <returns></returns>
		public bool Load(string filename)
		{
			try
			{
				// Parse the xml file from memory
				XmlDocument doc = new XmlDocument();
				doc.Load(filename);

				// Check the root node
				XmlElement xml = doc.DocumentElement;
				if (xml.Name.ToLower() != "dungeon")
				{
					Log.Send(new LogEventArgs(LogLevel.Error, "\"" + filename + "\" is not a valid bank file !", null));
					return false;
				}


				// For each nodes, process it
				XmlNodeList nodes = xml.ChildNodes;
				foreach (XmlNode node in nodes)
				{
					if (node.NodeType == XmlNodeType.Comment)
						continue;


					switch (node.Name.ToLower())
					{
						// Hero
						case "hero":
						{
						}
						break;


						// Level
						case "level":
						{
							Maze level = new Maze();
							level.Load(node);
							mazes.Add(node.Attributes["name"].Value, level);
						}
						break;

						// Start point
						case "start":
						{
							StartMazeName = node.Attributes["name"].Value;
							StartCoord = new Point(int.Parse(node.Attributes["x"].Value), int.Parse(node.Attributes["y"].Value));
						}
						break;

					}
				}


			}
			catch (Exception e)
			{

				Log.Send(new LogEventArgs(LogLevel.Error, e.Message, e.StackTrace));
				return false;
			}

			return true;
		}



		/// <summary>
		/// 
		/// </summary>
		/// <param name="filename"></param>
		/// <returns></returns>
		public bool Save(string filename)
		{
			return false;

		}



		#endregion


		/// <summary>
		/// Returns a maze by its name
		/// </summary>
		/// <param name="name"></param>
		/// <returns></returns>
		public Maze GetMaze(string name)
		{
			if (string.IsNullOrEmpty(name) || !mazes.ContainsKey(name))
				return null;

			return mazes[name];
		}



		#region Properties



		/// <summary>
		/// Gets a list of all levels
		/// </summary>
		public List<Maze> Mazes
		{
			get
			{
				List<Maze> list = new List<Maze>();

				foreach (Maze level in mazes.Values)
					list.Add(level);

				return list;
			}
		}
		Dictionary<string, Maze> mazes;


		/// <summary>
		/// Name of the level where the team start
		/// </summary>
		public string StartMazeName;


		/// <summary>
		/// Gets the starting level
		/// </summary>
		public Maze StartMaze
		{
			get
			{
				return GetMaze(StartMazeName);
			}
		}

		/// <summary>
		/// Coordinate where the team start
		/// </summary>
		public Point StartCoord;


		#endregion


	}

}
